package org.edu.isis.bravefox;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;

public class SocketCamera extends SurfaceView implements SurfaceHolder.Callback{
	public class SocketCameraThread extends Thread {
		
		private SurfaceHolder mSurfaceHolder;
		private boolean capturing = false;
		
		//Set the IP address of your pc 
		private final int SOCKET_TIMEOUT = 1000;
		private String address = "129.59.161.49";
		private int port = 9889;
		private Socket socket = null;
		
		//Others
		private final boolean preserveAspectRatio = true;
		private final Paint paint = new Paint();
		private int width = 480;
		private int height = 360;
		
		private Rect bounds;
		
		//constructor
		public SocketCameraThread(SurfaceHolder surfaceHolder, Context context){
			mSurfaceHolder = surfaceHolder;
			mContext = context;
		}
		
		public void connect(String ip, int wPx, int hPx, int nPort)
		{
			address = ip;
			width = wPx - 10;
			height = hPx - 10;
			port = nPort;
			
			bounds = new Rect(0, 0, width, height);
		}
		
		//methods
		public void setCapturing(boolean capturing) {
			this.capturing = capturing;
		}
		
		public boolean isCapturing() {
			return capturing;
		}
		
		@Override
		public void run() {
			 while (capturing) {
				 Canvas c = null;
				 try {
					 c = mSurfaceHolder.lockCanvas(null);
					 synchronized(mSurfaceHolder) {
						 try {
							 socket = new Socket();
							 socket.setSoTimeout(SOCKET_TIMEOUT);
							 //socket.bind(null);
							 socket.connect(new InetSocketAddress(address, port), SOCKET_TIMEOUT);
							 Log.i("Socket: ", ""+socket.isConnected());
							 //obtain the bitmap
							 InputStream in = socket.getInputStream();
							 Bitmap bitmap = BitmapFactory.decodeStream(in);
							 
							 //render it to canvas, scaling if necessary
							 if (
								bounds.right == bitmap.getWidth() &&
								bounds.bottom == bitmap.getHeight()) {
								 c.drawBitmap(bitmap, 0, 0, null);
							 } else {
								 Rect dest;
								 if (preserveAspectRatio) {
									 dest = new Rect(bounds);
									 dest.bottom = bitmap.getHeight() * bounds.right / bitmap.getWidth();
									 dest.offset(0, (bounds.bottom - dest.bottom)/2);
								 } else {
									 dest = bounds;
								 }
								 if (c !=null)
								 {
									 c.drawBitmap(bitmap, null, dest, paint);
								 }
							 }
						 } catch (SocketException e) {
							 /*Ignore*/
						 } catch (RuntimeException e) {
							 e.printStackTrace();
							 
						 } catch (IOException e) {
							 e.printStackTrace();
						 }finally {
							 try {
								 socket.close();
							 } catch (IOException e) {
							 /* ignore */
						 }
					 }
				 }
			 }catch (Exception e) {
				 e.printStackTrace();
			} finally {
				
				// do this in a finally so that if an exception is thrown
				// during the above, we don't leave the Surface in an 
				// inconsistent state
				if (c !=null) {
					mSurfaceHolder.unlockCanvasAndPost(c);
				}
			}
		 }
		 Log.i(LOG_TAG, "Socket Camera capture stopped");
	}
}
	
	private Context mContext;
	private SocketCameraThread csThread;
	
	private final String LOG_TAG = "SocketCamera:";
	
	public SocketCamera(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		SurfaceHolder holder = getHolder();
		holder.addCallback(this);
		
		csThread = new SocketCameraThread(holder,context);
	}
	
	public SocketCameraThread getThread(){
		return csThread;
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		csThread.setCapturing(true);
		csThread.start();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		
	}
}